package com.maimang.platform.crm.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.dingtalk.api.response.*;
import com.maimang.platform.common.mapper.SysUserMapper;
import com.maimang.platform.crm.service.DingTalkDeptService;
import com.maimang.platform.crm.service.DingTalkRoleService;
import com.maimang.platform.crm.service.DingTalkService;
import com.maimang.platform.crm.service.DingTalkUserService;
import com.maimang.platform.common.config.RoleKeyConstant;
import com.maimang.platform.common.config.SourceType;
import com.maimang.platform.common.entity.*;
import com.maimang.platform.common.service.*;
import com.maimang.platform.common.utils.ShiroUtils;
import com.maimang.platform.constant.UserConstants;
import com.maimang.platform.common.utils.UserUtil;
import com.maimang.platform.exception.BusinessException;
import com.maimang.platform.lang.StringUtils;
import com.maimang.platform.shiro.service.SysPasswordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Rocky
 * @version 1.0.0
 * @classname DingTalkServiceImpl
 * @description <br>钉钉数据信息同步service实现</br>
 * @date 2019-09-25 11:37
 * @email jintaozhao@qq.com
 */
@Service("dingTalkService")
public class DingTalkServiceImpl implements DingTalkService {

	private static final String DEFAULT_PASSWORD = "123456";

	@Autowired
	private DingTalkRoleService dingTalkRoleService;
	@Autowired
	private DingTalkDeptService dingTalkDeptService;
	@Autowired
	private DingTalkUserService dingTalkUserService;
	@Autowired
	private SysRoleService sysRoleService;
	@Autowired
	private SysDeptService sysDeptService;
	@Autowired
	private SysUserService sysUserService;
	@Autowired
	private SysRoleGroupService sysRoleGroupService;
	@Autowired
	private SysPostService sysPostService;

	@Autowired
	private SysPasswordService sysPasswordService;

	@Autowired
	private SysUserMapper sysUserMapper;

	/**
	 * 同步钉钉角色信息
	 *
	 * @throws Exception
	 */
	@Override
	public void getRoleList() throws Exception {
		syncRoleList(0L, 10L);
	}

	/**
	 * 批量重置密码
	 *
	 * @throws Exception
	 */
	@Override
	public void batchReset() throws Exception {
		SysUser user = new SysUser();
		List<SysUser> userList = sysUserService.selectUserList(user);
		for (int i = 0; i < userList.size(); i++) {
			SysUser sysUser = userList.get(i);
			if (!SysUser.isAdmin(sysUser.getUserId())) {
				sysUser.setSalt(ShiroUtils.randomSalt());
				sysUser.setPassword(sysPasswordService.encryptPassword(sysUser.getLoginName(), DEFAULT_PASSWORD, sysUser.getSalt()));
				sysUserMapper.updateUser(sysUser);
			}
		}
	}

	/**
	 * 同步部门信息
	 *
	 * @throws Exception
	 */
	@Override
	public void getDeptList() throws Exception {
		this.syncDeptList(StringUtils.EMPTY, false);
	}


	/**
	 * 同步用户信息
	 *
	 * @throws Exception
	 */
	@Override
	public void getUsers() throws Exception {
		List<Long> deptIdList = new ArrayList<>();
		deptIdList.add(1L);
		getAllSubDeptIdList("1", deptIdList);
		for (Long deptId : deptIdList) {
			this.getUsersByDept(deptId);
		}
	}


	private void getAllSubDeptIdList(String parentId, List<Long> deptIdList) throws Exception {
		if (deptIdList == null)
			deptIdList = new ArrayList<>();
		OapiDepartmentListIdsResponse response = dingTalkDeptService.getDeptIds(parentId);
		if (response.getErrcode() == 0L) {
			List<Long> deptIds = response.getSubDeptIdList();
			if (deptIds.size() > 0) {
				for (Long deptId : deptIds) {
					deptIdList.add(deptId);
					getAllSubDeptIdList(Long.toString(deptId), deptIdList);
				}
			} else {
				return;
			}
		}
	}


	/**
	 * 获取部门列表
	 *
	 * @param id         父部门id（如果不传，默认部门为根部门，根部门ID为1）
	 * @param fetchChild 是否递归部门的全部子部门，ISV微应用固定传递false
	 * @throws Exception
	 */
	private void syncDeptList(String id, Boolean fetchChild) throws Exception {
		OapiDepartmentListResponse departmentListResponse = dingTalkDeptService.getDeptList(id, fetchChild);
		List<OapiDepartmentListResponse.Department> departmentList = departmentListResponse.getDepartment();

		if (departmentList.size() > 0) {
			for (int i = 0; i < departmentList.size(); i++) {
				OapiDepartmentListResponse.Department department = departmentList.get(i);
				SysDept sysDept = sysDeptService.selectDeptById(department.getId());
				if (StringUtils.isNull(sysDept))
					sysDept = new SysDept();

				sysDept.setDeptId(department.getId());
				sysDept.setDeptName(department.getName());
				sysDept.setParentId(department.getParentid());
				sysDept.setOrderNum(String.valueOf(i + 1));

				if (StringUtils.isNotNull(sysDept.getDeptId())) {
					sysDeptService.deleteDeptRealById(sysDept.getDeptId());
				}
				sysDeptService.insertDept(sysDept);
				syncDeptList(department.getId().toString(), false);
			}
		} else {
			return;
		}
	}


	/**
	 * 根据部门获取用户信息
	 *
	 * @param deptId 部门编号
	 * @throws Exception
	 */
	private void getUsersByDept(Long deptId) throws Exception {
		if (deptId == 118960598 || deptId == 120360451) {
			System.out.println(deptId);
		}
		List<String> userids = dingTalkUserService.getDeptMember(deptId.toString());
		for (String userid : userids) {
			OapiUserGetResponse userGetResponse = dingTalkUserService.getUserByUserid(userid);
			this.saveUser(userGetResponse);
		}
	}

	/**
	 * 保存用户信息
	 *
	 * @param userGetResponse 钉钉返回的用户详情
	 */
	private void saveUser(OapiUserGetResponse userGetResponse) {
		if (userGetResponse == null) return;

		SysUser sysUser = sysUserService.selectUserByUserid(userGetResponse.getUserid());
		if (sysUser == null) {
			sysUser = new SysUser();
		}
		sysUser.setSalt(ShiroUtils.randomSalt());
		sysUser.setPassword(DEFAULT_PASSWORD);
		sysUser.setPassword(sysPasswordService.encryptPassword(sysUser.getLoginName(), sysUser.getPassword(), sysUser.getSalt()));

		if (StringUtils.isNotNull(sysUser.getUserId()) && SysUser.isAdmin(sysUser.getUserId())) {
			throw new BusinessException("不允许修改超级管理员用户");
		}

		// 设置部门列表
		List<Long> departments = userGetResponse.getDepartment();
		if (departments != null) {
			Long[] deptIds = new Long[departments.size()];
			for (int i = 0; i < departments.size(); i++) {
				deptIds[i] = departments.get(i);
			}
			sysUser.setDeptIds(deptIds);
		}

		// 设置角色列表 begin
		List<OapiUserGetResponse.Roles> roles = userGetResponse.getRoles();
		if (roles != null) {
			// 有管理角色
			Long[] roleIds = new Long[roles.size()];
			for (int i = 0; i < roles.size(); i++) {
				OapiUserGetResponse.Roles role = roles.get(i);
				roleIds[i] = role.getId();
			}
			sysUser.setRoleIds(roleIds);
		} else {
			// 没有角色即为普通员工角色
			SysRole role = sysRoleService.selectRolesByRoleKey("employee");
			Long[] roleIds = new Long[1];
			if (StringUtils.isNotNull(role))
				roleIds[0] = role.getRoleId();
			sysUser.setRoleIds(roleIds);
		}
		// end

		if (StringUtils.isNotEmpty(userGetResponse.getIsLeaderInDepts())) {
			if (!UserUtil.isSaleManager(userGetResponse.getName()))
				sysUser.setIsLeaderInDepts(userGetResponse.getIsLeaderInDepts());

			Map<Integer, Boolean> leaderMap = JSON.parseObject(userGetResponse.getIsLeaderInDepts(), HashMap.class);
			if (StringUtils.isNotNull(leaderMap)) {
				for (Map.Entry<Integer, Boolean> entry : leaderMap.entrySet()) {
					Integer key = entry.getKey();
					Long deptId = key.longValue();
					Boolean isLeader = entry.getValue();
					if (isLeader) {
						SysDept dept = sysDeptService.selectDeptById(Long.valueOf(deptId));
						if (StringUtils.isNotNull(dept)) {
							dept.setLeader(userGetResponse.getName());
							dept.setLeaderUserid(userGetResponse.getUserid());
							sysDeptService.updateDept(dept);
						}
					}
				}
			}
		}
		sysUser.setPosition(userGetResponse.getPosition());
		sysUser.setAvatar(userGetResponse.getAvatar());
		sysUser.setPhonenumber(userGetResponse.getMobile());
		sysUser.setUserid(userGetResponse.getUserid());
		sysUser.setUnionid(userGetResponse.getUnionid());
		sysUser.setOpenId(userGetResponse.getOpenId());
		sysUser.setJobNumber(userGetResponse.getJobnumber());
		sysUser.setHiredDate(userGetResponse.getHiredDate());
		sysUser.setWorkPlace(userGetResponse.getWorkPlace());
		sysUser.setIsAdmin(userGetResponse.getIsAdmin() ? "1" : "0");
		sysUser.setIsBoss(userGetResponse.getIsBoss() ? "1" : "0");
		sysUser.setUserType("01");
		sysUser.setEmail(userGetResponse.getEmail());
		sysUser.setOrgEmail(userGetResponse.getOrgEmail());
		sysUser.setUserName(userGetResponse.getName());
		sysUser.setLoginName(userGetResponse.getMobile());

		if (StringUtils.isNotNull(sysUser.getUserId()))
			sysUserService.updateUser(sysUser);
		else
			sysUserService.insertUser(sysUser);
	}

	/**
	 * @param deptId 部门id
	 * @param offset 偏移量
	 * @param size   每页记录数
	 * @param order  排序
	 * @throws Exception
	 */
	private void syncUsersByDept(Long deptId, Long offset, Long size, String order) throws Exception {
		OapiUserListbypageResponse response = dingTalkUserService.listByPage(deptId, offset, size, order);
		if (response.getErrcode() == 0L) {
			List<OapiUserListbypageResponse.Userlist> dingtalkUsers = response.getUserlist();
			for (int i = 0; i < dingtalkUsers.size(); i++) {
				saveUsers(dingtalkUsers.get(i));
			}
			if (response.getHasMore()) {
				offset += size;
				syncUsersByDept(deptId, offset, size, order);
			}
		}
	}

	/**
	 * 保存用户信息
	 *
	 * @param dingtalkUser 钉钉返回的用户信息
	 */
	private void saveUsers(OapiUserListbypageResponse.Userlist dingtalkUser) {
		if (dingtalkUser == null)
			return;
		SysUser sysUser = sysUserService.selectUserByLoginName(dingtalkUser.getName());
		if (sysUser == null) {
			sysUser = new SysUser();
			sysUser.setSalt(ShiroUtils.randomSalt());
			sysUser.setPassword(sysPasswordService.encryptPassword(sysUser.getLoginName(), sysUser.getPassword(), sysUser.getSalt()));
		}

		if (StringUtils.isNotNull(sysUser.getUserId()) && SysUser.isAdmin(sysUser.getUserId())) {
			throw new BusinessException("不允许修改超级管理员用户");
		}

		String department = dingtalkUser.getDepartment();
		JSONArray deptArr = JSON.parseArray(department.replace(" ", ""));
		Long[] deptIds = new Long[deptArr.size()];
		for (int i = 0; i < deptArr.size(); i++) {
			deptIds[i] = deptArr.getLong(i);
		}
		sysUser.setDeptIds(deptIds);
		sysUser.setPosition(dingtalkUser.getPosition());
		sysUser.setAvatar(dingtalkUser.getAvatar());
		sysUser.setPhonenumber(dingtalkUser.getMobile());
		sysUser.setUserid(dingtalkUser.getUserid());
		sysUser.setUnionid(dingtalkUser.getUnionid());
		sysUser.setJobNumber(dingtalkUser.getJobnumber());
		sysUser.setHiredDate(dingtalkUser.getHiredDate());
		sysUser.setWorkPlace(dingtalkUser.getWorkPlace());
		sysUser.setIsAdmin(dingtalkUser.getIsAdmin() ? "1" : "0");
		sysUser.setIsBoss(dingtalkUser.getIsBoss() ? "1" : "0");
		sysUser.setUserType("01");
		String email = StringUtils.isNotEmpty(dingtalkUser.getEmail()) ? dingtalkUser.getEmail() : dingtalkUser.getOrgEmail();
		sysUser.setEmail(email);
		sysUser.setUserName(dingtalkUser.getName());
		sysUser.setLoginName(dingtalkUser.getName());

		if (StringUtils.isNotNull(sysUser.getUserId()))
			sysUserService.updateUser(sysUser);
		else
			sysUserService.insertUser(sysUser);
	}

	/**
	 * 遍历角色列表
	 *
	 * @param offset 偏移量
	 * @param size   每页数据量
	 * @throws Exception
	 */
	private void syncRoleList(Long offset, Long size) throws Exception {
		OapiRoleListResponse roleListResponse = dingTalkRoleService.getRoleList(offset, size);
		offset += size;
		if (roleListResponse.getErrcode() == 0L) {
			OapiRoleListResponse.PageVo pageVo = roleListResponse.getResult();
			List<OapiRoleListResponse.OpenRoleGroup> openRoleGroups = pageVo.getList();
			if (openRoleGroups != null) {
				for (OapiRoleListResponse.OpenRoleGroup openRoleGroup : openRoleGroups) {
					// 保存角色组信息
					saveRoleGroup(openRoleGroup);
					// 保存角色信息
					saveRoles(openRoleGroup.getRoles(), openRoleGroup.getGroupId(), openRoleGroup.getName());
					// 保存岗位信息
					if (!openRoleGroup.getName().equalsIgnoreCase("默认")) {
						savePost(openRoleGroup.getRoles(), openRoleGroup.getName());
					}
				}
			}

			if (pageVo.getHasMore()) {
				syncRoleList(offset, size);
			} else {
				return;
			}
		}
	}

	/**
	 * 保存角色组信息
	 *
	 * @param openRoleGroup 钉钉返回的角色组信息
	 */
	private void saveRoleGroup(OapiRoleListResponse.OpenRoleGroup openRoleGroup) {
		SysRoleGroup roleGroup = new SysRoleGroup();
		Long groupId = openRoleGroup.getGroupId();
		String groupName = openRoleGroup.getName();
		roleGroup.setGroupId(String.valueOf(groupId));
		roleGroup.setGroupName(groupName);
		roleGroup.setDelFlag("0");
		SysRoleGroup temp = sysRoleGroupService.selectSysRoleGroupById(String.valueOf(groupId));
		if (temp != null) {
			sysRoleGroupService.updateSysRoleGroup(roleGroup);
		} else {
			sysRoleGroupService.insertSysRoleGroup(roleGroup);
		}
	}

	/**
	 * 同步角色信息
	 *
	 * @param openRoles 钉钉获取的角色信息（默认）
	 * @param groupId   角色组id
	 * @param groupName 角色组名称
	 */
	private void saveRoles(List<OapiRoleListResponse.OpenRole> openRoles, Long groupId, String groupName) {
		for (int i = 0; i < openRoles.size(); i++) {
			OapiRoleListResponse.OpenRole openRole = openRoles.get(i);
			SysRole role = new SysRole();
			String roleName = openRole.getName();
			role.setRoleId(openRole.getId());
			role.setRoleName(openRole.getName());
			role.setDelFlag("0");
			role.setSource(SourceType.DINGTALK);
			role.setGroupId(groupId);
			role.setGroupName(groupName);
			role.setRoleSort(String.valueOf(i));
			if (roleName.equalsIgnoreCase("负责人")) {
				role.setRoleKey(RoleKeyConstant.BOSS);
			} else if (roleName.equalsIgnoreCase("主管")) {
				role.setRoleKey(RoleKeyConstant.MANAGER);
			} else if (roleName.equalsIgnoreCase("主管理员")) {
				role.setRoleKey(RoleKeyConstant.MASTER_ADMIN);
			} else if (roleName.equalsIgnoreCase("子管理员")) {
				role.setRoleKey(RoleKeyConstant.SUB_ADMIN);
			} else {
				role.setRoleName("员工");
				role.setRoleKey(RoleKeyConstant.EMPLOYEE);
			}
			Long[] menuIds = new Long[0];
			role.setMenuIds(menuIds);
			String isUnique = sysRoleService.checkRoleKeyUnique(role);

			sysRoleService.deleteRoleById(role.getRoleId());
			if (isUnique.equalsIgnoreCase(UserConstants.ROLE_KEY_UNIQUE) && sysRoleService.selectRoleById(openRole.getId()) == null) {
				sysRoleService.insertRole(role);
			} else {
				sysRoleService.updateRole(role);
			}
		}
	}

	/**
	 * 同步岗位信息
	 *
	 * @param openRoles 钉钉获取的角色信息（职位/岗位）
	 * @param postGroup 岗位分属
	 */
	private void savePost(List<OapiRoleListResponse.OpenRole> openRoles, String postGroup) {
		for (int i = 0; i < openRoles.size(); i++) {
			OapiRoleListResponse.OpenRole openRole = openRoles.get(i);
			SysPost sysPost = new SysPost();
			sysPost.setPostId(openRole.getId());
			sysPost.setPostCode(postGroup);
			sysPost.setPostName(openRole.getName());
			sysPost.setStatus("0");
			sysPost.setPostSort(String.valueOf(i + 1));
			if (sysPostService.selectPostById(openRole.getId()) != null) {
				sysPostService.updatePost(sysPost);
			} else {
				sysPostService.insertPost(sysPost);
			}
		}
	}

}